<?php
declare(strict_types=1);

namespace Dreamcat\Http\EnhanceClient\Impl;

use Dreamcat\Http\EnhanceClient\Exception\Error;
use Dreamcat\Http\EnhanceClient\HttpClientInterface;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * 使用Guzzle做http请求客户端
 * @author vijay
 */
class GuzzleHttpClient implements HttpClientInterface
{
    /** @var ClientInterface Guzzle客户端 */
    private $client;
    /** @var int 默认的超时时间 */
    private $timeOutMs;

    /**
     * GuzzleParaleHttpClient constructor.
     * @param ClientInterface $client Guzzle客户端
     */
    public function __construct(ClientInterface $client = null)
    {
        $this->client = $client;
    }

    /**
     * @inheritDoc
     */
    public function sendRequest(RequestInterface $request, int $timeOutMs = null): ResponseInterface
    {
        try {
            $option = [];
            if ($timeOutMs === null && $this->getTimeOutMs() !== null) {
                $timeOutMs = $this->getTimeOutMs();
            }
            if ($timeOutMs !== null) {
                $option["timeout"] = $timeOutMs / 1000;
            }
            /** @noinspection PhpUnhandledExceptionInspection */
            return $this->getClient()->send($request, $option);
        } catch (Exception $e) {
            throw new Error($e->getMessage(), $e->getCode(), $e);
        }
    }

    /**
     * @return int 默认的超时时间
     */
    public function getTimeOutMs(): ?int
    {
        return $this->timeOutMs;
    }

    /**
     * @inheritDoc
     */
    public function setTimeOutMs(?int $timeOutMs): HttpClientInterface
    {
        $this->timeOutMs = $timeOutMs;
        return $this;
    }

    /**
     * @return ClientInterface Guzzle客户端
     */
    public function getClient(): ClientInterface
    {
        if (!$this->client) {
            $this->setClient(new Client(["http_errors" => false]));
        }
        return $this->client;
    }

    /**
     * @param ClientInterface $client Guzzle客户端
     * @return static 对象本身
     */
    public function setClient(ClientInterface $client): GuzzleHttpClient
    {
        $this->client = $client;
        return $this;
    }
}

# end of file
